<!-- 角色权限分配弹窗 -->
<template>
  <a-modal :width="460" title="分配权限" :visible="visible" :confirm-loading="loading" @update:visible="updateVisible" @ok="save">
    <a-spin :spinning="authLoading">
      <div style="height: 60vh" class="ele-scrollbar-hover">
        <a-tree
          checkable
          :tree-data="authData"
          :replaceFields="{ children: 'children', title: 'name', key: 'id', value: 'id' }"
          v-model:expandedKeys="expandKeys"
          v-model:checkedKeys="checkedKeys"
        />
      </div>
    </a-spin>
  </a-modal>
</template>

<script>
import { SysRoleApi } from '@/api/SysRoleApi';
import { SysMenuApi } from '@/api/SysMenuApi';

export default {
  name: 'SysRoleMenuButton',
  emits: ['update:visible'],
  props: {
    // 弹窗是否打开
    visible: Boolean,
    // 当前角色数据
    data: Object
  },
  data() {
    return {
      // 权限数据
      authData: [],
      // 权限数据请求状态
      authLoading: false,
      // 提交状态
      loading: false,
      // 角色权限展开的keys
      expandKeys: [],
      // 角色权限选中的keys
      checkedKeys: []
    };
  },
  watch: {
    visible() {
      if (this.visible) {
        this.query();
      }
    }
  },
  methods: {
    /**
     * 数组是否有某些值
     * @param array {Array<String>} 数组
     * @param obj {String, Array<String>} 值
     * @returns {boolean}
     */
    arrayHas(array, obj) {
      if (!obj) {
        return true;
      }
      if (!array) {
        return false;
      }
      if (Array.isArray(obj)) {
        for (let i = 0; i < obj.length; i++) {
          if (array.indexOf(obj[i]) === -1) {
            return false;
          }
        }
        return true;
      }
      return array.indexOf(obj) !== -1;
    },
    /**
     * 查询权限数据
     *
     * @author chenjinlong
     * @date 2021/4/7 11:00
     */
    query() {
      this.authData = [];
      this.expandKeys = [];
      this.checkedKeys = [];
      if (!this.data) {
        return;
      }
      this.authLoading = true;

      let roleId = this.data.roleId;
      SysMenuApi.getMenuList({ roleId })
        .then(res => {
          this.authLoading = false;
          if (res.code === '00000') {
            let eks = [],
              cks = [];
            res.data.forEach(d => {
              eks.push(d.id);
            });
            this.authData = this.$util.toTreeData(res.data, 'id', 'pid');
            this.$util.eachTreeData(this.authData, d => {
              if (d.checked && (!d.children || !d.children.length)) {
                cks.push(d.id);
              }
            });
            this.expandKeys = eks;
            this.checkedKeys = cks;
          } else {
            this.$message.error(res.message);
          }
        })
        .catch(e => {
          this.authLoading = false;
          this.$message.error(e.message);
        });
    },
    /**
     * 保存权限分配
     *
     * @author chenjinlong
     * @date 2021/4/7 11:00
     */
    save() {
      this.loading = true;
      let grantMenuIdList = [];
      let grantMenuButtonIdList = [];
      this.$util.eachTreeData(this.authData, d => {
        if (this.checkedKeys.some(c => c === d.id)) {
          if (d.menuFlag) {
            grantMenuIdList.push(d.id);
          } else {
            //更改-判断按钮的上级id是否存在
            if (!this.arrayHas(grantMenuIdList, d.pid)) {
              grantMenuIdList.push(d.pid);
            }
            grantMenuButtonIdList.push({ buttonId: d.id, buttonCode: d.buttonCode });
          }
        }
      });
      SysRoleApi.grantMenuAndButton({
        grantMenuIdList: grantMenuIdList,
        grantMenuButtonIdList: grantMenuButtonIdList,
        roleId: this.data.roleId
      })
        .then(res => {
          this.loading = false;
          if (res.code === '00000') {
            this.$message.success(res.message);
            this.updateVisible(false);
          } else {
            this.$message.error(res.message);
          }
        })
        .catch(e => {
          this.loading = false;
          this.$message.error(e.message);
        });
    },
    /* 更新visible */
    updateVisible(value) {
      this.$emit('update:visible', value);
    }
  }
};
</script>

<style scoped>
</style>
